package il.ac.technion.cs236700.address_book;

import static org.junit.Assert.*;

import il.ac.technion.cs236700.address_book.Contact;
import il.ac.technion.cs236700.address_book.Defaults;
import il.ac.technion.cs236700.address_book.Person;
import il.ac.technion.cs236700.address_book.Defaults.ESUPPORTED_KEYS;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class Contact_Test {

	protected Contact newContact(){		
		return new Contact(buildStubMap());
	}
	
	private Contact newContact(Map<String, String> m) {
		m.putAll(buildStubMap());		
		return new Contact(m);
	}

	private Map<String, String> buildStubMap() {
		Map<String,String> values = new HashMap<String, String>();
		values.put(Defaults.getValue(ESUPPORTED_KEYS.FirstName), "benny");
		values.put(Defaults.getValue(ESUPPORTED_KEYS.LastName), "menny");
		values.put(Defaults.getValue(ESUPPORTED_KEYS.Email), "benny@t2");
		return values;
	}
	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test	
	public void testConflictsWith() {
		Contact c = newContact();
		Map<String,String> m = new HashMap<String, String>();
		m.put(Defaults.getValue(ESUPPORTED_KEYS.Company), "RACorp");
		Contact c2 = newContact(m);
		assertEquals(c.conflictsWith(c2), false);
		c2.setNewEntry(Defaults.getValue(ESUPPORTED_KEYS.Email), "regev@stud");
		assertEquals(c.conflictsWith(c2), true);
	}

	@Test
	public void testCanUnify() {
		Contact c = newContact();
		Map<String,String> m = new HashMap<String, String>();
		m.put(Defaults.getValue(ESUPPORTED_KEYS.Company), "RACorp");
		m.put(Defaults.getValue(ESUPPORTED_KEYS.Email), "");
		Contact c2 = newContact(m);
		assertEquals(c.canUnify(c2), true);
		c2.setFirstName("Bobo");
		assertEquals(c.canUnify(c2), false);
		c2.setFirstName("benny");
		c2.removeEntry(Defaults.getValue(ESUPPORTED_KEYS.Company));
		c2.setNewEntry(Defaults.getValue(ESUPPORTED_KEYS.Homepage), "www.google.com");
		assertEquals(c.canUnify(c2), true);
	}


	@Test
	public void testUnify() {
		String k_company = Defaults.getValue(ESUPPORTED_KEYS.Company);
		Contact c = newContact();
		Map<String,String> m = new HashMap<String, String>();
		m.put(k_company, "RACorp");
		m.put(Defaults.getValue(ESUPPORTED_KEYS.Email), "");
		Contact c2 = newContact(m);
		assertEquals(c.canUnify(c2), true);
		c.unify(c2);
		assertEquals(c.getMap().get(k_company), "RACorp");
	}

	@Test
	public void testContains() {
		Contact c = newContact();
		assertEquals(c.contains(new Person("benny","menny",null)), true);
		assertEquals(c.contains(new Person("benny","denny",null)), false);
		/**
		 *	check that DBC exists if contact has no first name - passed 
		 */
		//c.setFirstName(null);
		//assertEquals(c.contains(new Person("Regev","Azr",null)), false);
	}

	@Test
	public void testOutput() {
		Contact c = newContact();
		String actual = "benny@t2,menny,benny";
		String actual2 = "benny,menny,benny@t2";
		ArrayList<String> fields = new ArrayList<String>();
		fields.add(Defaults.getValue(ESUPPORTED_KEYS.FirstName));
		fields.add(Defaults.getValue(ESUPPORTED_KEYS.LastName));
		fields.add(Defaults.getValue(ESUPPORTED_KEYS.Email));
		assertEquals(c.output(), actual);
		assertEquals(c.output(fields), actual2);
	}

	@Test
	public void testEqualsObject() {
		Contact c = newContact();
		assertEquals(c.equals(new Contact(buildStubMap())), true);
		Contact c2 = c.clone();
		c2.setFirstName("Moshe");
		assertEquals(c.equals(c2), false);
	}

	@Test
	public void testFirstName() {
		Contact c = newContact();
		assertEquals(c.FirstName(), "benny");
	}

	@Test
	public void testLastName() {
		Contact c = newContact();
		assertEquals(c.LastName(), "menny");
	}

	@Test
	public void testSetValues() {
		Contact c = newContact();
		assertEquals(c.getMap(), buildStubMap());
	}
	
	@Test
	public void testaddToMap(){
		Contact c = newContact();
		Map<String, String> m = new HashMap<String, String>();
		m.put("Home Address", "RACorp");
		c.addToMap(m);
		assertEquals(c.getMap().get("Home Address"), "RACorp");
	}
	@Test
	public void testsetValue() {
		Contact c = newContact();
		Map<String, String> values = new HashMap<String, String>();
		values.put(Defaults.getValue(ESUPPORTED_KEYS.FirstName), "Sharon");
		values.put(Defaults.getValue(ESUPPORTED_KEYS.LastName), "Ronen");
		c.setValue(values);
		assertEquals(c.FirstName(), "Sharon");
		assertEquals(c.LastName(), "Ronen");
	}
	
	@Test
	public void testcontainMap(){
		Contact c = newContact();
		Map<String, String> values = new HashMap<String, String>();
		values.put(Defaults.getValue(ESUPPORTED_KEYS.FirstName), "benny");
		values.put(Defaults.getValue(ESUPPORTED_KEYS.LastName), "menny");
		assertEquals(c.containMap(values), true);
	}
}
